First Example

SELECT e.name, e.sal, m.name, m.sal
  FROM emp as e, emp as m
 WHERE e.mgr_id = m.id
   AND e.sal > m.sal;
out(En, Es, Mn, Ms) :- emp(Eid, En, Es, Em), emp(Em, Mn, Ms, Mm),
                       (Es > Ms).

The Syntax of Basic Datalog

Program ::= Clause+ Query*
Clause ::= Fact | Rule
Fact ::= Predicate '.'
Rule ::= Predicate ':-' Body '.'
Body ::= Literal (',' Literal)*
Literal ::= Predicate
Predicate ::= Identifier '(' Arguments ')'
Arguments ::= Term (',' Term)*
Term ::= Identifier | Variable | Constant
Query ::= '?-' Predicate '.'
Identifier ::= letter (letter | digit)*
Variable ::= uppercase_letter (letter | digit)*
Constant ::= lowercase_letter (letter | digit)* | '"' any_character_except_double_quote '"'

Transitive Closure, Hydro.run Playground

 .static edge `vec![(1, 2), (2, 3), (3,4)]`
 .output out 
 .output out `for_each(|t| println("{:?}", t))`

-- transitive closure of edges in a graph
path(X, Y) :- edge(X, Y).
path(X, Y) :- path(X, Z), edge(Z, Y).
out(Y) :- path(X, Y), (X == 0).

Semi-Naive Rewrite

Initialize:

path_new() = .
path_delta() = .

While (not fixpoint):

1.

path_new(X, Y) :- edge(X, Y).
path_new(X, Y) :- path_delta(X, Y), edge(X, Y).

2.

path(X, Y) :- path_delta(X, Y);
path_delta = path_new;
path_new = ∅;

Semi-Naive Rewrite 2

Before:

path(X, Y) :- edge(X, Y).
path(X, Y) :- path(X, Z), path(Z, Y).

After:

path(X, Y) :- edge(X, Y).
path(X, Y) :- path(X, Z), path_delta(Z, Y).
path(X, Y) :- path_delta(X, Z), path(Z, Y).
path(X, Y) :- path_delta(X, Z), path_delta(Z, Y).

Proof Trees

Here is a proof tree of the fact path(1,4) for our original edges and paths example:

flowchart TD
direction LR
subgraph proof[" "]
direction BT
    e12["edge(1,2)"] --> p12["path(1,2)"] --> p13["path(1,3)"]
    e13["edge(2,3)"] --> p13 --> p14["edge(1,4)"]
    e34["edge(3,4)"] --> p14
end

Proof Trees 2

flowchart TD
direction LR
subgraph proof1[" "]
direction BT
    e12["edge(1,2)"] --> p12["path(1,2)"] --> p13["path(1,3)"]
    e23["edge(2,3)"] --> p13 --> p14["edge(1,4)"]
    e34["edge(3,4)"] --> p34["path(3,4)"] --> p14
end
subgraph proof2[" "]
direction BT
    e'12["edge(1,2)"] --> p'12["path(1,2)"] --> p'14["path(1,4)"]
    e'23["edge(2,3)"] --> p'23["path(2,3)"] --> p'24["path(2,4)"]
    e'34["edge(3,4)"] --> p'34["path(3,4)"] --> p'24
    p'24 --> p'14
end

Predicate Dependency Graph

%%{init: {'theme':'forest'}}%%

flowchart LR
subgraph s0["Stratum 0"]
    edge --> path
    path --> path
end
subgraph s1["Stratum 1"]
    path -- ¬ --> unreachable
end